package com.phcx.corporate.controller;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.phcx.corporate.model.*;
import com.phcx.corporate.service.*;
import com.phcx.corporate.utils.ModelUtil;
import com.phcx.corporate.utils.SessionUtil;
import com.phcx.corporate.utils.TableUtil;
import com.phcx.corporate.vo.AdminInfoDataVoOne;
import com.phcx.corporate.vo.AdminInfoQueryVo;
import com.phcx.corporate.vo.AdminInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

/*
 * @Author: zmh
 * @Date: 2023/05/18/13:38
 * @Description: 管理员管理接口：登录、注册、分页查询、根据id查询、更新、删除、批量删除、解锁与锁定、验证用户名是否重复、登出、权限获取
 */
@CrossOrigin
@RestController
@Slf4j
@RequestMapping("/admin")
public class AdminInfoController{

    @Autowired
    private AdminInfoService adminService;

    @Autowired
    private UserLogService userLogService;

    @Autowired
    private RegOfficeService regOfficeService;

    @Autowired
    private UserLogContentService userLogContentService;

    // 登录
    @RequestMapping("/login")
    public Result<String> login(@RequestBody AdminInfo admin, HttpServletRequest request){

        // 根据登录信息查询数据库 status为1
        admin.setStatus("1");
        admin.setPassword(SecureUtil.md5(admin.getPassword()));

        QueryWrapper<AdminInfo> adminInfoQueryWrapper = new QueryWrapper<>(admin);

        AdminInfo result = adminService.getOne(adminInfoQueryWrapper);
        // 登录成功
        if(result!=null){

            // 将登录信息放到session中
            HttpSession session = request.getSession();
            session.setAttribute("admin",result);
            session.setMaxInactiveInterval(30*60);

            QueryWrapper<RegOffice> regOfficeQueryWrapper = new QueryWrapper<>();
            regOfficeQueryWrapper.eq("licence_42_code",result.getLicence42Code());
            RegOffice regInfo = regOfficeService.getOne(regOfficeQueryWrapper);
            if(regInfo!=null){
                session.setAttribute("regInfo",regInfo);
            }
            session.setAttribute("regInfo",regInfo);

            // 获取用户的企业信息
            QueryWrapper<RegOffice> regOfficeWrapper = new QueryWrapper<>();
            regOfficeWrapper.eq("licence_42_code",result.getLicence42Code());
            RegOffice regOffice = regOfficeService.getOne(regOfficeWrapper);

            if(regOffice!=null){
                session.setAttribute("regOffice",regOffice);
            }


//            loginAdmin.put(result.getAdminId(),result);

            // 插入登录日志
            UserLog userLog = new UserLog();        // 组装登录日志信息
            userLog.setLogId(TableUtil.getID());
            userLog.setLogType("3");
            userLog.setOperatorUsername(admin.getUsername());
            userLog.setTargetUsername(admin.getUsername());
            userLog.setLicence42Code(result.getLicence42Code());
            userLog.setLogDate(TableUtil.getLogTime());

            boolean flag = userLogService.save(userLog);
            if (flag) {
                return Result.ok();
            }else {
                log.info("[登录日志插入失败]");
            }
            return Result.ok();
        }else {
            return Result.fail("用户名与密码不匹配");
        }
    }

    // AdminInDataVo转化为AdminInfo



    // 注册
    @RequestMapping("/register")   // 1.级联选择器单选时用的AdminInfo/2.多选时用AdminInDataVo
    public Result<String> register(@RequestBody AdminInfoDataVoOne adminVo, HttpServletRequest request){

        AdminInfo adminInfo = SessionUtil.sessionExpiration(request);
        if (adminInfo == null){
            return Result.fail("session过期");
        }


        // 1.级联选择器单选
//        admin.setLicence42Code(admin.getLicence42Code().trim().replaceAll("^,|,$", ""));
        AdminInfo admin = ModelUtil.adminVo2Info(adminVo);


        // 检查用户名是否重复
        AdminInfo flag = adminService.getOne(new QueryWrapper<AdminInfo>().eq("username", admin.getUsername()));
        if(flag!=null){
            return Result.fail();
        }

        log.info("[密码加密]");
        String plainPsd = admin.getPassword();
        admin.setPassword(SecureUtil.md5(plainPsd));


        AdminInfo operator = (AdminInfo) request.getSession().getAttribute("admin");
        admin.setLastEditAdminId(operator.getAdminId());
        admin.setLastEditDate(TableUtil.getLogTime());
        admin.setRegisterAdminId(operator.getAdminId());

       //  2.级联选择器多选
//         AdminInfo admin = ModelUtil.adminVo2Info(adminVo);




        boolean save = adminService.save(admin);

        if(save){
            try {
                // 组装注册日志信息 插入到 用户管理日志表
                UserLog userLog = new UserLog();
                userLog.setLogId(TableUtil.getID());
                userLog.setLogType("1");
                userLog.setOperatorUsername(operator.getUsername());
                userLog.setTargetUsername(admin.getUsername());
                userLog.setLicence42Code(admin.getLicence42Code());
                userLog.setLogDate(TableUtil.getLogTime());
                userLogService.save(userLog);
            }catch (Exception e) {
                e.printStackTrace();
            }
            return Result.ok();
        }else{
            return Result.fail();
        }
    }


    // 分页查询
    @RequestMapping("/findAdminList/{current}/{limit}")
    public Result<Page<AdminInfoVo>> findAdminList(@PathVariable Integer current, @PathVariable("limit") Integer size,
                                                   @RequestBody(required = false) AdminInfoQueryVo queryVo ,
                                                   HttpServletRequest request){
        // 判断session是否过期
        AdminInfo adminInfo = SessionUtil.sessionExpiration(request);
        if (adminInfo == null){
            return Result.fail();
        }

        // 获取操作人信息
        AdminInfo operator = (AdminInfo) request.getSession().getAttribute("admin");
        String accountType = operator.getAccountType();

        // 构造page对象
        Page<AdminInfo> page = new Page<>(current, size);
        // 构造查询条件
        LambdaQueryWrapper<AdminInfo> wrapper = new LambdaQueryWrapper<>();
        if (accountType.equals("1")){
            wrapper.eq(!StringUtils.isEmpty(queryVo.getUsername()),AdminInfo::getUsername,queryVo.getUsername())
                    .eq(AdminInfo::getAccountType,"0")
                    .eq(AdminInfo::getRegisterAdminId,operator.getAdminId())
                    .like(!StringUtils.isEmpty(queryVo.getAdminName()),AdminInfo::getAdminName,queryVo.getAdminName());
        }else{
            wrapper.eq(!StringUtils.isEmpty(queryVo.getUsername()),AdminInfo::getUsername,queryVo.getUsername())
                    .like(!StringUtils.isEmpty(queryVo.getAdminName()),AdminInfo::getAdminName,queryVo.getAdminName());
        }

        Page<AdminInfo> page1 = adminService.page(page, wrapper);



        // 整理需要返回的数据
        List<AdminInfo> adminList = page1.getRecords();
        List<AdminInfoVo> adminInfoVos = new ArrayList<>();
        AdminInfoVo adminInfoVo = null;
        try{
            for (AdminInfo admin : adminList) {
                // 处理每一个 AdminInfo 对象
                // 根据登记机关代码获取登记机关名称
                String code = admin.getLicence42Code();
                if (!StringUtils.isEmpty(code)){
                    QueryWrapper<RegOffice> queryWrap = new QueryWrapper<>();
                    queryWrap.eq("licence_42_code",code);
                    RegOffice reg = regOfficeService.getOne(queryWrap);
                    if(reg!=null){
                        adminInfoVo = new AdminInfoVo();
                        // 组装数据
                        adminInfoVo.setAdminId(admin.getAdminId());
                        adminInfoVo.setUsername(admin.getUsername());
                        adminInfoVo.setAdminName(admin.getAdminName());
                        adminInfoVo.setLicence42(reg.getLicence42());
                        adminInfoVo.setLicence42Code(code);
                        adminInfoVo.setAccountType(admin.getAccountType());
                        adminInfoVo.setLocation(reg.getRegLocation());
                        adminInfoVo.setStatus(admin.getStatus());
                        adminInfoVos.add(adminInfoVo);
                    }else{
                        adminInfoVo = new AdminInfoVo();
                        // 组装数据
                        adminInfoVo.setAdminId(admin.getAdminId());
                        adminInfoVo.setUsername(admin.getUsername());
                        adminInfoVo.setAdminName(admin.getAdminName());
                        adminInfoVo.setLicence42("");
                        adminInfoVo.setLicence42Code(code);
                        adminInfoVo.setAccountType(admin.getAccountType());
                        adminInfoVo.setLocation("");
                        adminInfoVo.setStatus(admin.getStatus());
                        adminInfoVos.add(adminInfoVo);
                    }

                }else{
                    adminInfoVo = new AdminInfoVo();
                    // 组装数据
                    adminInfoVo.setAdminId(admin.getAdminId());
                    adminInfoVo.setUsername(admin.getUsername());
                    adminInfoVo.setAdminName(admin.getAdminName());
                    adminInfoVo.setLicence42("");
                    adminInfoVo.setLicence42Code("");
                    adminInfoVo.setAccountType(admin.getAccountType());
                    adminInfoVo.setLocation("");
                    adminInfoVo.setStatus(admin.getStatus());
                    adminInfoVos.add(adminInfoVo);
                }

            }
        }catch (Exception e) {
            e.printStackTrace();
        }

        Page<AdminInfoVo> newPage = new Page<>(current, size);

        newPage.setRecords(adminInfoVos);

        //设置总条数
        newPage.setTotal(page1.getTotal());
        //设置每页显示条数（不设置会导致分页信息错误）
        newPage.setSize(size);
        newPage.setCurrent(current);

        return Result.ok(newPage);
    }


    // 根据id获取管理员信息
    @GetMapping("/getAdminInfo/{id}")
            // 级联多选设置
    public Result<AdminInfoDataVoOne> findAdminById(@PathVariable("id") String adminId, HttpServletRequest request){
        AdminInfo adminInfo1 = SessionUtil.sessionExpiration(request);
        if (adminInfo1 == null){
            return Result.fail();
        }

        AdminInfo adminInfo = adminService.getById(adminId);
        // 级联单选多选需要更改的AdminInfoDataVo与AdminInfoDataVoOne
        AdminInfoDataVoOne adminInDataVo = ModelUtil.adminInDataVo(adminInfo);
        return Result.ok(adminInDataVo);
    }


    /**
     *  更新管理员信息
     *  插入更新前后的信息
     */
    @PostMapping("/updateAdminInfo")
    @Transactional                                        // 级联多选设置
    public Result<AdminInfo> updateAdminInfo(@RequestBody AdminInfoDataVoOne adminInDataVo,HttpServletRequest request){

        // 校验session
        AdminInfo adminInfo1 = SessionUtil.sessionExpiration(request);
        if (adminInfo1 == null){
            return Result.fail();
        }

        // 将提交的admin信息转化成实体
        AdminInfo adminInfo = ModelUtil.adminVo2Info(adminInDataVo);

        // 判断密码是否更改
        String password = adminInfo.getPassword();
        String adminId = adminInfo.getAdminId();
        LambdaQueryWrapper<AdminInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminInfo::getAdminId,adminId);
        AdminInfo adminData = adminService.getOne(wrapper);
        if (!adminData.getPassword().equals(password)) {
            log.info("[密码加密]");
            // 如果更改 将密码加密
            adminInfo.setPassword(SecureUtil.md5(password));
        }
        // 如果没有更改 无需加密

        // 设置被修改人记录中的操作人信息、时间
        AdminInfo operator = (AdminInfo) request.getSession().getAttribute("admin");
        adminInfo.setLastEditAdminId(operator.getAdminId());
        adminInfo.setLastEditDate(TableUtil.getLogTime());

        AdminInfo Before = adminService.getById(adminInfo.getAdminId());
        //
        boolean flag = adminService.updateById(adminInfo);
        AdminInfo admin = adminService.getById(adminInfo.getAdminId());

        try {
            if(flag){
                // 记录更新日志
                UserLog userLog = new UserLog();
                String userLogId = TableUtil.getID();
                userLog.setLogId(userLogId);
                userLog.setLogType("2");
                userLog.setOperatorUsername(operator.getUsername());
                userLog.setTargetUsername(admin.getUsername());
                userLog.setLicence42Code(admin.getLicence42Code());
                userLog.setLogDate(TableUtil.getLogTime());
                boolean result = userLogService.save(userLog);
                log.info("[管理员信息变更结果]:"+result);

                // 记录更新前后的信息    更新日志id、更改前、更改后
                UserLogContent userLogContent = new UserLogContent(userLogId, Before.toString(), admin.toString());
                userLogContentService.save(userLogContent);

                return Result.ok();
            }else {
                return Result.fail();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(flag){
                return Result.ok();
            }
        }

        return Result.ok();
    }


    // 根据id注销
    @DeleteMapping("/delete/{adminId}")
    public Result<?> deleteById(@PathVariable String adminId,HttpServletRequest request){

        AdminInfo adminInfo1 = SessionUtil.sessionExpiration(request);
        if (adminInfo1 == null){
            return Result.fail();
        }

        AdminInfo admin = adminService.getById(adminId);

        AdminInfo operator = null;

        // 更改被修改用户的执行人、修改时间
        try{
            operator = (AdminInfo) request.getSession().getAttribute("admin");
            admin.setLastEditAdminId(operator.getAdminId());
            admin.setLastEditDate(TableUtil.getLogTime());
            adminService.updateById(admin);
        }catch (Exception e) {
            e.printStackTrace();
        }

        boolean b = adminService.removeById(adminId);

        try {
            // 插入日志
            UserLog userLog = new UserLog();
            String userLogId = TableUtil.getID();
            userLog.setLogId(userLogId);
            userLog.setLogType("0");
            userLog.setOperatorUsername(operator.getUsername());
            userLog.setTargetUsername(admin.getUsername());
            userLog.setLicence42Code(admin.getLicence42Code());
            userLog.setLogDate(TableUtil.getLogTime());
            userLogService.save(userLog);
            return Result.ok();
        }catch (Exception e) {
            e.printStackTrace();
        }
        if(b){
            return Result.ok();
        }
        return Result.fail();
    }

    // 根据id批量注销
    @DeleteMapping("/batchRemove")
    public Result<?>  batchRemove(@RequestBody List<String> idList,HttpServletRequest request){

        AdminInfo adminInfo1 = SessionUtil.sessionExpiration(request);
        if (adminInfo1 == null){
            return Result.fail();
        }

        int count = 0;

        for (String id : idList) {
            deleteById(id, request);
            count++;
        }
        if(idList.size()==count){
            return Result.ok();
        }else {
            return Result.fail();
        }
    }

    // 解锁、锁定用户
    @PutMapping("/lockAdmin/{id}/{status}")
    public Result<?> lockAdmin(@PathVariable String id, @PathVariable String status, HttpServletRequest request){

        AdminInfo adminInfo1 = SessionUtil.sessionExpiration(request);
        if (adminInfo1 == null){
            return Result.fail();
        }

        // 设置用户状态
        AdminInfo admin = adminService.getById(id);
        admin.setStatus(status);

        boolean flag = adminService.updateById(admin);
        if(flag){

            // 将用户的被修改时间与执行人id、被修改时间进行修改
            try {
                AdminInfo operator = (AdminInfo) request.getSession().getAttribute("admin");
                String operatorId = operator.getAdminId();
                String logTime = TableUtil.getLogTime();
                admin.setLastEditAdminId(operatorId);
                admin.setLastEditDate(logTime);
                adminService.updateById(admin);
            }catch (Exception e) {
                e.printStackTrace();
            }
            return Result.ok();
        }else {
            return Result.fail();
        }
    }


    // 校验用户名是否重复
    @GetMapping("/verUsername/{username}")
    public Result<?> verUsername(@PathVariable String username){
        QueryWrapper<AdminInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        AdminInfo one = adminService.getOne(wrapper);
        if (one != null) {
            return Result.fail();
        }
        return Result.ok();
    }

    // 登出接口
    @RequestMapping("/logout")
    public Result<?> logout(HttpServletRequest request, HttpServletResponse response){
        log.info("[退出登录]==>清除session");
        request.getSession().invalidate();
        return Result.ok();
    }

    // 获取登录人的权限信息
    @RequestMapping("/getAuth")
    public Result<String> getAuth(HttpServletRequest request){
        String auth = "";
        AdminInfo adminInfo = (AdminInfo) request.getSession().getAttribute("admin");
        auth = adminInfo.getAccountType();
        return Result.ok(auth);
    }

    // 获取登录人的权限信息
    @RequestMapping("/getName")
    public Result<String> getName(HttpServletRequest request){
        String name = "";
        AdminInfo adminInfo = (AdminInfo) request.getSession().getAttribute("admin");
        name = adminInfo.getAdminName();
        return Result.ok(name);
    }

}
